package cc.rengu.igas.mcps.core.realize.impl;

import cc.rengu.igas.channel.cups.common.constant.CupsConfigConstant;
import cc.rengu.igas.mcps.common.constant.McpsParamConstant;
import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.model.AcctAndFeeType;
import cc.rengu.igas.mcps.core.realize.PosParamDealService;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.BinInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.BinInfoService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.BinInfoServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlConfigUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

/*
 * Create by fuyp on 2020-6-26
 * pos公共函数处理接口
 */
public class PosParamDealServiceImpl implements PosParamDealService {
    private final RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    @Override
    public String getCupsReconKey(String instId, String mchntNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        String txnDate = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TXN_DATE);
        String txnTime = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TXN_TIME);
        /* 获取银联第7域 */
        String region7 = txnDate.substring(4, 8) + txnTime;
        /* 获取银联11域 */
        String region11 = sysSeqNum.substring(26, 32);
        /* 获取银联收单机构号 */
        String acqInstCode = XmlConfigUtil.getXmlConfigCacheKeyValue(CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_ACQ_INS_CODE);
        String fwdInstCode = XmlConfigUtil.getXmlConfigCacheKeyValue(CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_FWD_INS_CODE);
        /* 获取银联商户信息 */
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo || StringUtil.isEmptyOrNull(mchntInfo.getCupsInstId())) {
            rglog.warn("获取银联收单机构号失败，默认为配置的银联收单机构号", instId);
        } else {
            if (!StringUtil.isEmptyOrNull(acqInstCode) && StringUtil.isEmptyOrNull(mchntInfo.getCupsAreaCode())) {
                acqInstCode = acqInstCode.substring(0, 4) + mchntInfo.getCupsAreaCode();
            }
        }
        /* 返回银联联统一对账KEY */
        return region7 + region11 + acqInstCode + fwdInstCode;
    }

    @Override
    public String getRefNo() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String refNo;
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        /* 获取年的除10余数 */
        String strDate = DateUtil.getCurrentDate();
        int indexYear = Integer.parseInt(strDate.substring(0, 4)) % 10;
        int indexMonth = (Integer.parseInt(strDate.substring(4, 6)) * 31 + Integer.parseInt(strDate.substring(6, 8))) % 1000;
        refNo = String.format("%01d", indexYear) + String.format("%03d", indexMonth) + sysSeqNum.substring(sysSeqNum.length() - 8);
        return refNo;
    }

    @Override
    public String genCupsAcqInstCode(String instId, String mchntNo) throws Exception {
        String acqInstCode = XmlConfigUtil.getXmlConfigCacheKeyValue(CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_ACQ_INS_CODE);
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo || StringUtil.isEmptyOrNull(mchntInfo.getCupsInstId())) {
            /*未获取到银联子商户*/
            rglog.error("获取银联收单机构号失败", instId);
        } else {
            if (!StringUtil.isEmptyOrNull(acqInstCode) && StringUtil.isEmptyOrNull(mchntInfo.getCupsAreaCode())) {
                acqInstCode = acqInstCode.substring(0, 4) + mchntInfo.getCupsAreaCode();
            }
        }
        return acqInstCode;
    }

    @Override
    public AcctAndFeeType judgeOwnOtherBank(String instId, String cardNo, String supportAcctType) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID), McpsParamConstant.OPMS_SYS_PARAM, McpsParamConstant.CORPORATION_ORG_CODE);
        if (null == sysParam || null == sysParam.getParamStatus()) {
            rglog.info("法人行机构编码未配置或配置失效,instId:<{}>", instId);
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        /* 获取卡bin信息 */
        BinInfoService binInfoService = new BinInfoServiceImpl();
        BinInfo binInfo = binInfoService.getCardBinInfo(cardNo);
        if (null == binInfo) {
            rglog.info("未获取到卡BIN信息:卡号<{}>", cardNo);
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        /* 获取卡类型  借贷记 */
        String cardType = binInfo.getCardType();
        String temp;
        AcctAndFeeType acctAndFeeType = new AcctAndFeeType();
        /*判断本行卡*/
        if (sysParam.getParamValue().contains(binInfo.getIssuerCode().substring(0, 4))) {
            switch (cardType) {
                /*借记卡*/
                case "1":
                    /*本借账户类型 赋值*/
                    acctAndFeeType.setAcctType("00");
                    /*本借费率类型赋值*/
                    acctAndFeeType.setFeeType("01");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(0, 1);
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持本行借记卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
                /*贷记卡*/
                case "2":
                    /*本贷账户类型 赋值*/
                    acctAndFeeType.setAcctType("01");
                    /*本借费率类型赋值*/
                    acctAndFeeType.setFeeType("02");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(1, 2);
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持本行贷记卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
                /*准贷记卡*/
                case "3":
                    /*准贷记账户类型 赋值*/
                    acctAndFeeType.setAcctType("01");
                    /*本贷费率类型赋值*/
                    acctAndFeeType.setFeeType("02");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(1, 2);
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持本行准贷记卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
                /*预付卡*/
                case "4":
                    /*预付卡账户类型 赋值*/
                    acctAndFeeType.setAcctType("00");
                    /*本借费率类型赋值*/
                    acctAndFeeType.setFeeType("01");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(1, 2);
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持本行预付卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
            }
        }
        /*判断他行卡*/
        else {
            /*判断借记卡*/
            switch (cardType) {
                /*借记卡*/
                case "1":
                    /*他借账户类型 赋值*/
                    acctAndFeeType.setAcctType("10");
                    /*本借费率类型赋值*/
                    acctAndFeeType.setFeeType("11");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(4, 5);
                        /*判断是否支持此类卡*/
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持他行借记卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
                /*判断贷记卡*/
                case "2":
                    /*他贷账户类型 赋值*/
                    acctAndFeeType.setAcctType("11");
                    /*本借费率类型赋值*/
                    acctAndFeeType.setFeeType("12");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(5, 6);
                        /*判断是否支持此类卡*/
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持他行贷记卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
                /*准贷记卡*/
                case "3":
                    /*准贷记账户类型 赋值*/
                    acctAndFeeType.setAcctType("11");
                    /*本贷费率类型赋值*/
                    acctAndFeeType.setFeeType("12");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(1, 2);
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持他行准贷记卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
                /*预付卡*/
                case "4":
                    /*预付卡账户类型 赋值*/
                    acctAndFeeType.setAcctType("10");
                    /*本借费率类型赋值*/
                    acctAndFeeType.setFeeType("11");
                    if (!StringUtil.isEmptyOrNull(supportAcctType) && !"*".equals(supportAcctType)) {
                        temp = supportAcctType.substring(1, 2);
                        if (!AppParamConstant.YES.equals(temp)) {
                            rglog.error("该交易不支持他行预付卡！！");
                            throw new BizException(RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespCode(), RespCodeEnum.ACCT_TYPE_NOT_SUPPORT.getRespDesc());
                        }
                    }
                    break;
            }
        }
        rglog.debug("账户类型及费率类型为:{}", JSON.toJSONString(acctAndFeeType));
        return acctAndFeeType;
    }
}
